package com.yllt4cloud.ddauth.filter;

import com.alibaba.fastjson.JSONException;
import com.yllt4cloud.common.core.constant.CacheConstants;
import com.yllt4cloud.common.core.util.ResultResp;
import com.yllt4cloud.common.ddbase.constant.ErrorCode;
import com.yllt4cloud.common.ddbase.constant.entity.SessionEntity;
import com.yllt4cloud.common.ddbase.util.Base64Utils;
import com.yllt4cloud.common.ddbase.util.CommonRedisUtil;
import com.yllt4cloud.common.ddbase.util.JsonUtil;
import com.yllt4cloud.common.ddbase.util.response.ResponseUtil;
import com.yllt4cloud.ddauth.service.impl.ClerkConfirmAuthorityServiceImpl;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;

public class LoginFilter extends BaseFilter{

	private static final Logger LOGGER = LoggerFactory.getLogger(LoginFilter.class);

//	private static final String LOGIN_SUFFIX = "login";
//	private static final String JS_SUFFIX = ".js";
//	private static final String CSS_SUFFIX = ".css";
//	private static final String HTML_SUFFIX = ".html";

	@Autowired
	private RedisTemplate redisTemplate;

	@Autowired
	private  ClerkConfirmAuthorityServiceImpl clerkConfirmAuthorityService;
	@Autowired
    CommonRedisUtil loginRedis;

	@Override
	public void destroy() {

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {

		redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(String.class));

		if(isFilter(request)){
			try {
				chain.doFilter(request, response);
			}catch (Exception e) {
				LOGGER.error(e.getMessage(),e);
			}
			return;
		}
//		request.getParameter()
		/**
		 * 1.判断session是否为空  --->登录后操作  app
		 * 2.获取session  base64解析  和本地比对
		 * 3.校验接口权限
		 */
//		request = changeToParameterRequestWrapper(request);
		//获取sessionid
//		ServletRequest request2 = new ParameterRequestWrapper((HttpServletRequest) request, request.getParameterMap());
//		Object session = ((HttpServletRequest)request).getParameter("session");
		Object session = request.getParameter("session");
	    if(null==session){
			session=redisTemplate.opsForHash().get(CacheConstants.DD_IP_SESSION_CONTAINER, request.getRemoteAddr());
//					LoginAct.getIpSessionMap().get(request.getRemoteAddr());
		}
		try {
			//判断session是否为空
			if(session == null){
                LOGGER.info("快去登录!!!!!!!");
				ResponseUtil.processError(response, ResultResp.fail("请登录之后在操作", ErrorCode.NEED_LOGIN));
				return;
			}
            //夜总会之前 下面这块代码放在 baseFile 类中
//			InvocationContext invocationContext = new InvocationContext();
//			ApplicationContext.CTX.openThreadLocal(invocationContext);
//			ApplicationContext.CTX.setRequest((HttpServletRequest) request);
           //----------------
			//用本地编码
			String contents = new String(Base64Utils.decode(session.toString()));
            Map<String, Object> sessionMap=null;
           try {
               sessionMap = JsonUtil.parseMap(contents);
           }catch (Exception e){
               ResponseUtil.processError(response, ResultResp.fail("参数格式错误", ErrorCode.AUTHORITY_FAIL));
               return;
           }

			String token = (String) sessionMap.get("token");
			String sessionId = (String) sessionMap.get("user");

			LOGGER.info("token-{},sessionId-{}",token,sessionId);

			SessionEntity sessionEntity = (SessionEntity)loginRedis.getSessionEntity(sessionId);
//					UserSessionContainer.instance().get(sessionId);
			//有登录要求的才有用户信息
			if (null == sessionEntity) {
				ResponseUtil.processError(response, ResultResp.fail("session不正确", ErrorCode.INVALID_SESSION));
				return;
			}
//			UserUtil.bind(sessionEntity);
//			UserSessionContainer.instance().put(sessionId, sessionEntity);

//			redisTemplate.opsForHash().put(CacheConstants.DD_SESSION_CONTAINER, sessionId, sessionEntity);
	        String key = sessionEntity.getEncryptKey();
	        //签名校验(session中的token和本地token必须一致)
	        if (!token.equals(sessionEntity.getToken())) {
	        	ResponseUtil.processError(response, ResultResp.fail("签名校验失败", ErrorCode.KEY_ERROR));
	            return;
	        }
	        //是否有权限操作接口  需要根据权限进行设置。
	        String url = ((HttpServletRequest) request).getRequestURI().replace(((HttpServletRequest) request).getContextPath(), "").replaceAll("/+","/");



//			ClerkConfirmAuthorityServiceImpl clerkConfirmAuthorityService = (ClerkConfirmAuthorityServiceImpl)SpringContextUtil.getBean("clerkConfirmAuthorityServiceImpl");

			//验证 员工   当前请求的url  在 base_confirmauthority 中，却不在 base_authoritymode 中的权限，员工是否有权限
			if(!clerkConfirmAuthorityService.checkNotInTabAuthoritymodeUrl(sessionEntity.getUserInfo().getClerkId().intValue(), url)) {
				ResponseUtil.processError(response, ResultResp.fail("权限不足", ErrorCode.AUTHORITY_FAIL));
				return;
			}


	        if (null == key) {
				ResponseUtil.processError(response, ResultResp.fail("请登录之后在操作", ErrorCode.NEED_LOGIN));
	            return;
	        }
		}catch(JSONException e){
			LOGGER.error("json格式转换错误" + e.getMessage(), e);
			ResponseUtil.processError(response, ResultResp.fail("json格式错误", ErrorCode.JSON_PARSE_ERROR));
		} catch (Exception e) {
			LOGGER.error("处理异常" + e.getMessage(), e);
			ResponseUtil.processError(response, ResultResp.fail("处理失败", ErrorCode.PROCESS_ERROR));
		}
		try {
			chain.doFilter(request, response);
		}catch (Exception e) {
			LOGGER.error(e.getMessage(),e);
		}
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		// TODO Auto-generated method stub

	}

	/*public ParameterRequestWrapper changeToParameterRequestWrapper(ServletRequest request){
		Map<String,String[]> m = new HashMap<String,String[]>(request.getParameterMap());

		request = new ParameterRequestWrapper((HttpServletRequest)request, m);
		String contentType = request.getContentType();


		if(contentType != null && contentType.startsWith("multipart/form-data")){
			try {
                DiskFileItemFactory factory = new DiskFileItemFactory();
                ServletContext servletContext  = request.getServletContext();
                File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
                factory.setRepository(repository);
//				DiskFileUpload upload = new DiskFileUpload();
//				List fileItems = upload.parseRequest((HttpServletRequest) request);
                ServletFileUpload upload = new ServletFileUpload(factory);
                Iterator<FileItem> iter = upload.parseRequest((HttpServletRequest) request).iterator();
//				Iterator iter = fileItems.iterator();
				while (iter.hasNext()) {
					FileItem item = (FileItem) iter.next();
					item.getInputStream();
					if (!item.isFormField()) {
						// 文件流
					} else {
						// 非文件流
						String value = item.getString();
						value = new String(value.getBytes("ISO-8859-1"), "UTF-8");

						if(value != null)
							m.put(item.getFieldName(), new String[]{value.toString()});
					}
				}
		} catch (Exception e) {
			// TODO: handle exception
		}

		}
		return new ParameterRequestWrapper((HttpServletRequest)request, m);
	}
*/

	/**
	 *
	 * <p><b>作用：</b>获取登陆session数据</p>
	 * <p><b>日期：</b>2016-3-23 下午1:51:56</p>
	 * <p><b>作者：</b>yaozq</p>
	 * @param request
	 * @return
	 * @exception
	 */
	public Object getSession(ServletRequest request){

		String contentType = request.getContentType();


		if(contentType != null && contentType.startsWith("multipart/form-data")){
			try {
                DiskFileItemFactory factory = new DiskFileItemFactory();
                ServletContext servletContext  = request.getServletContext();
                File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
                factory.setRepository(repository);
//				DiskFileUpload upload = new DiskFileUpload();
//				List fileItems = upload.parseRequest((HttpServletRequest) request);
                ServletFileUpload upload = new ServletFileUpload(factory);
                Iterator<FileItem> iter = upload.parseRequest((HttpServletRequest) request).iterator();
//				Iterator iter = fileItems.iterator();
				while (iter.hasNext()) {
					FileItem item = (FileItem) iter.next();
					item.getInputStream();
					if (!item.isFormField()) {
						// 文件流
					} else {
						// 非文件流
						String value = item.getString();
						value = new String(value.getBytes("ISO-8859-1"), "UTF-8");

						if("session".equals(item.getFieldName())){

							return value;
						}
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

		}
		return ((HttpServletRequest)request).getParameter("session");
	}
}
